<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./d3.v5.min.js"></script>
</head>

<body>

  <div id="app">

  </div>
  <hr>
  <button id="btn_add">add</button>
  <button id="btn_update">update</button>

  <script>

    const chart_width = 600;
    const chart_height = 400;
    const padding = 30;
    var dataset = [50, 100.150, 200, 250];
    let container = d3.select('#app');
    var sort_flag = false;

    //创建画布
    let svg = container.append('svg')
      .attr('width', chart_width)
      .attr('height', chart_height)
      .style('background', '#efefef')

    let x_scale = d3.scaleBand()
      .domain(d3.range(dataset.length))
      .range([padding, chart_width - padding])
      .paddingInner(0.05)

    let y_scale = d3.scaleLinear()
      .domain([0, d3.max(dataset)])
      .range([0, chart_height - padding])


    function addRect() {

      svg.selectAll('rect')
        .data(dataset)
        .enter()
        .append('rect')
        .attr('fill', 'grey')
        .on('click', function () {
          sort();
        })
        .on('mouseover', function () {
          d3.select(this).style('fill', 'orange')
        })
        .on('mouseout', function () {
          d3.select(this).style('fill', 'grey')
        })

      svg.selectAll('rect')
        .transition()
        .duration(500)
        .attr('width', x_scale.bandwidth())
        .attr('height', function (d) {
          return y_scale(d);
        })
        .attr('x', function (d, i) {
          return x_scale(i);
        })
        .attr('y', function (d, i) {
          return chart_height - y_scale(d);
        })

    }


    function addText() {

      svg.selectAll('text').data(dataset)
        .enter()
        .append('text')
        .text(function (d) {
          return d;
        })


      svg.selectAll('text').data(dataset)
        .attr('x', function (d, i) {
          return x_scale(i) + x_scale.bandwidth() / 2;
        })
        .attr('y', function (d, i) {
          return chart_height - y_scale(d)
        })
        .attr('text-anchor', 'middle')

    }


    function sort() {
      d3.selectAll('rect').sort(function (a, b) {
        return sort_flag ? d3.descending(a, b) : d3.ascending(a, b);
      }).transition()
        .duration(500)
        .attr('x', function (d, i) {
          return x_scale(i);
        })
        .attr('y', function (d, i) {
          return chart_height - y_scale(d);
        })


      svg.selectAll('text').sort(function (a, b) {
        return sort_flag ? d3.descending(a, b) : d3.ascending(a, b);
      }).transition()
        .duration(500)
        .attr('x', function (d, i) {
          return x_scale(i) + x_scale.bandwidth() / 2
        })
        .attr('text-anchor', 'middle')

      sort_flag = !sort_flag;
    }

    function updateScale() {
      x_scale.domain(d3.range(dataset.length))
      y_scale.domain([0, d3.max(dataset)])
    }

    d3.select('#btn_add')
      .on('click', () => {
        var num = Math.floor(Math.random() * 300);
        dataset.push(num);
        updateScale();
        addRect();
        addText();
      })

    d3.select('#btn_update')
      .on('click', () => {
        dataset = [60, 90, 222, 77, 345, 459, 99];
        updateScale();
        addRect();
        addText();
      })

    addRect();
    addText();
  </script>

</body>

</html>